<?php

/**
 * SimplifyPHP Framework
 *
 * This file is part of SimplifyPHP Framework.
 *
 * SimplifyPHP Framework is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * SimplifyPHP Framework is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * @author Rodrigo Rutkoski Rodrigues, <rutkoski@gmail.com>
 */

/**
 * Default request manager.
 *
 * @author Rodrigo Rutkoski Rodrigues <rutkoski@gmail.com>
 * @package Simplify_Kernel
 */
class RequestImpl extends Dictionary implements IRequest
{

  public $filters = array();

  /**
   * @var unknown_type parseable extensions.
   */
  protected $extensions = array(
    'xml', 'html?', 'json'
  );

  /**
   * Check if this is an AJAX request.
   *
   * @return boolean
   */
  public static function isAjax()
  {
    return getenv('HTTP_X_REQUESTED_WITH') === "XMLHttpRequest";
  }

  /**
   * Check if this is a JSON request.
   *
   * @return boolean
   */
  public function isJSON()
  {
    return Simplify::getConfig()->get('parse_extension') && $this->get('extension') == 'json';
  }

  /**
   * Check if this is an XML request.
   *
   * @return boolean
   */
  public function isXML()
  {
    return Simplify::getConfig()->get('parse_extension') && $this->get('extension') == 'xml';
  }

  /**
   *
   * @return string
   */
  public function getIp()
  {
    if (! empty($_SERVER['HTTP_CLIENT_IP'])) {
      $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (! empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
      $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
    } else {
      $ip = $_SERVER['REMOTE_ADDR'];
    }

    return $ip;
  }

  /**
   *
   * @return unknown_type
   */
  public function __construct()
  {
    parent::__construct();

    if (isset($_POST['sid'])) {
      $this->set('sid', $_POST['sid']);
    }
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/IRequest#parse()
   */
  public function initialize()
  {
    // fix for IIS
    if (! isset($_SERVER['REQUEST_URI'])) {
      if (isset($_SERVER['REQUEST_URI'])) {
        $_SERVER['REQUEST_URI'] = $_SERVER['REQUEST_URI'];
      }
      elseif (isset($_SERVER['QUERY_STRING'])) {
        $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'] . '?' . $_SERVER['QUERY_STRING'];
      }
      else {
        $_SERVER['REQUEST_URI'] = $_SERVER['SCRIPT_NAME'];
      }
    }

    if (isset($_SERVER['REQUEST_URI'])) {
      $uri = $_SERVER['REQUEST_URI'];
    }
    else {
      $uri = $_SERVER['ORIG_PATH_INFO'];
    }

    $secure = empty($_SERVER["HTTPS"]) ? '' : ($_SERVER["HTTPS"] == "on") ? "s" : "";
    $protocol = substr(strtolower($_SERVER["SERVER_PROTOCOL"]), 0, strpos(strtolower($_SERVER["SERVER_PROTOCOL"]), "/")) . $secure;

    $url = urldecode(Simplify::getConfig()->get('url_protocol') . '://' . $_SERVER['HTTP_HOST'] . $uri);

    // get stuff from url (use of pretty url, query string...)
    $app_root = '(?:(index\.php)?\??/?)?';
    $extension = Simplify::getConfig()->get('parse_extension') ? sprintf('(?:\.(%s))?', implode('|', $this->extensions)) : '';

    $r = sprintf('#^%s/%s(.*?)%s(?:\?.*)?$#', Simplify::getConfig()->get('app_url'), $app_root, $extension);

    // usually, this happens when SY_APP_URL is incorrect
    if (! preg_match($r, $url, $url_parts)) {
      throw new ApplicationException(sprintf('app_url might not be set correctly: <b>%s</b>. Please check your config file.', Simplify::getConfig()->get('app_url')));
    }

    $route = $query_string = '/' . sy_get_param($url_parts, 2, '');

    if (false !== ($p = strpos($route, '?'))) {
      $route = substr($route, 0, $p);
    }

    $this->set('domain', $_SERVER['HTTP_HOST']);
    $this->set('uri', $uri);
    $this->set('url', $url);
    $this->set('method', $_SERVER['REQUEST_METHOD']);
    $this->set('self', sy_get_param($url_parts, 1, pathinfo($_SERVER['SCRIPT_NAME'], PATHINFO_BASENAME)));
    $this->set('extension', sy_get_param($url_parts, 3, ''));
    $this->set('route', $route);
    $this->set('ip', $this->getIp());

    if (count($_POST)) {
      $this->set('post', new SimpleDictionary(sy_add_slashes_deep($_POST)));
    }

    if (count($_GET)) {
      $this->set('get', new SimpleDictionary(sy_add_slashes_deep($_GET)));
    }
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/api/IRequest#filter_in($route)
   */
  public function filter_in($route)
  {
    foreach ($this->filters as $filter) {
      $route = $filter->unpack($route);
    }

    return $route;
  }

  /**
   * (non-PHPdoc)
   * @see simplify/kernel/api/IRequest#filter_out($route)
   */
  public function filter_out($route)
  {
    foreach ($this->filters as $filter) {
      $route = $filter->pack($route);
    }

    return $route;
  }

  /**
   * Test if $route matches current requested route.
   */
  public function match($regex, $true, $false = '')
  {
    $regex = '|^'.$regex.'$|i';
    $match = preg_match($regex, $this->get('route')) ? $true : $false;
    return $match;
  }

}

?>